#include "network_app.h"
#include "network_board.h"
#include "485_protocol.h"
#include "rs485_app.h"
#include "led_board.h"
#include "user_wwdg.h"

#if _NETWOK_FUNCTION_ENABLE_
/**
 * @brief 构建与命令相对应的报文
 *
 * @param Command          - 命令
 * @param pDataOut         - 构建后的数据流
 * @param pSizeOut         - 数据流长度
 * @param pResponseTimeOut - 命令响应时间
 * @return bool            - （true：成功 false：失败）
 */
static bool NetworkConstructMessageCorrespondingCommand(NetworkCommandTable_t Command, void *Parm, uint8_t *pDataOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief 根据命令解析报文
 *
 * @param Command                 - 命令
 * @param pDataIn                 - 报文数据流
 * @param pDataSizeIn             - 报文数据流长度
 * @return NetworkExecuteResult_t - 解析结果
 */
static NetworkExecuteResult_t NetworkParsingMessagesBasedOnCommands(NetworkCommandTable_t Command, const void *pDataIn, uint16_t pDataSizeIn);

/**
 * @brief 响应报文解析结果
 *
 * @param Result - 响应结果
 * @return bool  - 解析结果（true：成功 false：失败）
 */
static bool NetworkResponseMessageParsingResult(NetworkExecuteResult_t Result);

/**
 * @brief 上报命令执行结果
 *
 * @param Command - 命令
 * @param Result  - 结果
 */
static void NetworkReportingCommandExecutionResults(NetworkCommandTable_t Command, bool Result);

/**
 * @brief 接收数据完成回调
 *
 */
static void NetworkDataReceivedCallback(void);

/**
 * @brief 命令操作回调
 *
 */
static void NetworkCommandOperationCallback(void);

/**
 * @brief 唤醒回调
 *
 */
static void NetworkAirborneAwakeningCallback(void);

static NetworkTaskApi_t NetworkTaskApi = {0};
static NetworkDataPacket_t NetworkDataPacket = {0};
static NetworkBitStatus_t NetworkBitStatus = {0};
static uint8_t EleControlBoardRetryComuniTimesArray[MAX_NUMBLER_OF_ELE_CONTROL_BOARD] = {0}; // 梯控主板重试通信次数
/**
 * @brief 主机状态
 */
static HostBitStatus_t HostBitStatus = {0};

static bool NetworkConstructMessageCorrespondingCommand(NetworkCommandTable_t Command, void *Parm, uint8_t *pDataOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut)
{
  PRINT("[network] : NetworkConstructMessageCorrespondingCommand\r\n");
  bool BuildResult = false;

  if ((pDataOut != NULL) && (pSizeOut != NULL))
  {
    switch (Command)
    {
    case NETWORK_SELF_TEST:
    {
      if (NetworkTaskApi.SelfTestCallback.Sending != NULL)
      {
        BuildResult = NetworkTaskApi.SelfTestCallback.Sending(pDataOut, pSizeOut, pResponseTimeOut);
      }
    }
    break;

    case NETWORK_RESET_SYSTEM_STATUS:
    {
      if (NetworkTaskApi.ResetSystemStatusCallback.Sending != NULL)
      {
        BuildResult = NetworkTaskApi.ResetSystemStatusCallback.Sending(pDataOut, pSizeOut, pResponseTimeOut);
      }
    }
    break;

    case NETWORK_FORCE_EXIT_COMMAND_MODE:
    {
      if (NetworkTaskApi.ForceExitCommandModeCallback.Sending != NULL)
      {
        BuildResult = NetworkTaskApi.ForceExitCommandModeCallback.Sending(pDataOut, pSizeOut, pResponseTimeOut);
      }
    }
    break;

    case NETWORK_INITIATE_NET_ATTACHMENT:
    {
      if (NetworkTaskApi.InitiateNetAttachmentCallback.Sending != NULL)
      {
        BuildResult = NetworkTaskApi.InitiateNetAttachmentCallback.Sending(pDataOut, pSizeOut, pResponseTimeOut);
      }
    }
    break;

    case NETWORK_GET_IO_BOARD_VERSION:
    {
      if (NetworkTaskApi.GetVersionCallback.Sending != NULL)
      {
        BuildResult = NetworkTaskApi.GetVersionCallback.Sending(Parm, pDataOut, pSizeOut, pResponseTimeOut);
      }
    }
    break;

    case NETWORK_OPEN_SPECIFIC_FLOOR:
    {
      if (NetworkTaskApi.OpenSpecificFloorCallback.Sending != NULL)
      {
        BuildResult = NetworkTaskApi.OpenSpecificFloorCallback.Sending(Parm, pDataOut, pSizeOut, pResponseTimeOut);
      }
    }
    break;

    case NETWORK_OPEN_EMERGENCY_MODE:
    {
      if (NetworkTaskApi.OpenEmergencyModeCallback.Sending != NULL)
      {
        BuildResult = NetworkTaskApi.OpenEmergencyModeCallback.Sending(Parm, pDataOut, pSizeOut, pResponseTimeOut);
      }
    }
    break;

    case NETWORK_ELEVATOR_IO_BOARD_FIRMWARE_TRANS:
    {
      if (NetworkTaskApi.ElevatorIoBoardFirmwareTransCallback.Sending != NULL)
      {
        BuildResult = NetworkTaskApi.ElevatorIoBoardFirmwareTransCallback.Sending(Parm, pDataOut, pSizeOut, pResponseTimeOut);
      }
    }
    break;

    case NETWORK_QUERY_IO_BOARD_MAC_ADDRESS:
    {
      if (NetworkTaskApi.QueryIoBoardMacAddressCallback.Sending != NULL)
      {
        BuildResult = NetworkTaskApi.QueryIoBoardMacAddressCallback.Sending(Parm, pDataOut, pSizeOut, pResponseTimeOut);
      }
    }
    break;

    case NETWORK_QUERY_OTA_STATUS:
    {
      if (NetworkTaskApi.ElevatorIoBoardQueryOtaStatusCallback.Sending != NULL)
      {
        BuildResult = NetworkTaskApi.ElevatorIoBoardQueryOtaStatusCallback.Sending(Parm, pDataOut, pSizeOut, pResponseTimeOut);
      }
    }
    break;

    case NETWORK_SET_BOARD_SELF_TEST_MODE:
    {
      if (NetworkTaskApi.SetBoardSelfTestModeCallback.Sending != NULL)
      {
        BuildResult = NetworkTaskApi.SetBoardSelfTestModeCallback.Sending(Parm, pDataOut, pSizeOut, pResponseTimeOut);
      }
    }
    break;

    case NETWORK_SET_BOARD_FIRE_ALARM_WORK_MODE:
    {
      if (NetworkTaskApi.SetBoardFireAlarmWorkModeCallback.Sending != NULL)
      {
        BuildResult = NetworkTaskApi.SetBoardFireAlarmWorkModeCallback.Sending(Parm, pDataOut, pSizeOut, pResponseTimeOut);
      }
    }
    break;
  
    case NETWORK_QUERY_BOARD_FIRE_ALARM_STATUS:
    {
      if (NetworkTaskApi.QueryBoardFireAlarmStatusCallback.Sending != NULL)
      {
        BuildResult = NetworkTaskApi.QueryBoardFireAlarmStatusCallback.Sending(Parm, pDataOut, pSizeOut, pResponseTimeOut);
      }
    }
    break;
    }
  }

  return BuildResult;
}

static NetworkExecuteResult_t NetworkParsingMessagesBasedOnCommands(NetworkCommandTable_t Command, const void *pDataIn, uint16_t pDataSizeIn)
{
  NetworkExecuteResult_t ParsingResult = NETWORK_MESSAGE_EXECUTE_ERROR;

  if (pDataIn != NULL)
  {
    switch (Command)
    {

    case NETWORK_OPEN_SPECIFIC_FLOOR:
    {
      if (NetworkTaskApi.OpenSpecificFloorCallback.Parsing != NULL)
      {
        ParsingResult = NetworkTaskApi.OpenSpecificFloorCallback.Parsing(pDataIn, pDataSizeIn);
      }
    }
    break;

    case NETWORK_GET_IO_BOARD_VERSION:
    {
      if (NetworkTaskApi.GetVersionCallback.Parsing != NULL)
      {
        ParsingResult = NetworkTaskApi.GetVersionCallback.Parsing(pDataIn, pDataSizeIn);
      }
    }
    break;

    case NETWORK_OPEN_EMERGENCY_MODE:
    {
      if (NetworkTaskApi.OpenEmergencyModeCallback.Parsing != NULL)
      {
        ParsingResult = NetworkTaskApi.OpenEmergencyModeCallback.Parsing(pDataIn, pDataSizeIn);
      }
    }
    break;

    case NETWORK_ELEVATOR_IO_BOARD_FIRMWARE_TRANS:
    {
      if (NetworkTaskApi.ElevatorIoBoardFirmwareTransCallback.Parsing != NULL)
      {
        ParsingResult = NetworkTaskApi.ElevatorIoBoardFirmwareTransCallback.Parsing(pDataIn, pDataSizeIn);
      }
    }
    break;

    case NETWORK_QUERY_OTA_STATUS:
    {
      if (NetworkTaskApi.ElevatorIoBoardQueryOtaStatusCallback.Parsing != NULL)
      {
        ParsingResult = NetworkTaskApi.ElevatorIoBoardQueryOtaStatusCallback.Parsing(pDataIn, pDataSizeIn);
      }
    }
    break;

    case NETWORK_QUERY_IO_BOARD_MAC_ADDRESS:
    {
      if (NetworkTaskApi.QueryIoBoardMacAddressCallback.Parsing != NULL)
      {
        ParsingResult = NetworkTaskApi.QueryIoBoardMacAddressCallback.Parsing(pDataIn, pDataSizeIn);
      }
    }
    break;

    case NETWORK_SET_BOARD_SELF_TEST_MODE:
    {
      if (NetworkTaskApi.SetBoardSelfTestModeCallback.Parsing != NULL)
      {
        ParsingResult = NetworkTaskApi.SetBoardSelfTestModeCallback.Parsing(pDataIn, pDataSizeIn);
      }
    }
    break;

    case NETWORK_SET_BOARD_FIRE_ALARM_WORK_MODE:
    {
      if (NetworkTaskApi.SetBoardFireAlarmWorkModeCallback.Parsing != NULL)
      {
        ParsingResult = NetworkTaskApi.SetBoardFireAlarmWorkModeCallback.Parsing(pDataIn, pDataSizeIn);
      }
    }
    break;

    case NETWORK_QUERY_BOARD_FIRE_ALARM_STATUS:
    {
      if (NetworkTaskApi.QueryBoardFireAlarmStatusCallback.Parsing != NULL)
      {
        ParsingResult = NetworkTaskApi.QueryBoardFireAlarmStatusCallback.Parsing(pDataIn, pDataSizeIn);
      }
    }
    break;
    }
  }

  return ParsingResult;
}

static bool NetworkResponseMessageParsingResult(NetworkExecuteResult_t Result)
{
  bool ResponseResult = false;
  PRINT("[network]: -------->NetworkResponseMessageParsingResult = %d\r\n", Result);

  switch (Result)
  {
  case NETWORK_MESSAGE_EXECUTE_SUCCESS:
  {
    PRINT("[network]: message parsed successfully.\r\n");

    ResponseResult = true;
    NetworkBitStatus.NumberOfTimesSent = 0;
    NetworkBitStatus.MessageExecuteStep = WIRELESS_USER_ACTION_RESPONSE;

    NetworkStartCommandOperationTaskNoWait();
  }
  break;

  case NETWORK_MESSAGE_EXECUTE_RETRY:
  {
    ResponseResult = true;

    PRINT("[network]: re-request device status.\r\n");

    NetworkBitStatus.NumberOfTimesSent = 0;
    NetworkBitStatus.MessageExecuteStep = WIRELESS_USER_ACTION_RESPONSE;
    NetworkDelayedStartCommandOperationTask(WIRELESS_INTERVAL_OF_QUERY_EXECUTE_STATUS);
  }
  break;

  case NETWORK_MESSAGE_EXECUTE_OVER:
  {
    PRINT("[network]: command is executed.\r\n");

    ResponseResult = true;
    NetworkBitStatus.CommandExecuteResult = true;
    NetworkBitStatus.MessageExecuteStep = WIRELESS_MESSAGE_RESPONSE_COMPLETE;
    NetworkStartCommandOperationTaskNoWait();
  }
  break;

  case NETWORK_MESSAGE_EXECUTE_WAIT:
  {
    PRINT("[network]: Wait for the network module to return the command execution result.\r\n");

    ResponseResult = false;
    NetworkBitStatus.MessageExecuteStep = WIRELESS_MESSAGE_DELIVERY_TIMEOUT;
    NetworkDelayedStartCommandOperationTask(WIRELESS_WAIT_COMMAND_RETURN_TIMEOUT);
  }
  break;

  default:
  {
    ResponseResult = true;

    if (NetworkBitStatus.NumberOfRetries < WIRELESS_MAX_NUMBER_OF_SEND)
    {
      PRINT("[network]: received false, re-execute the relevant commands.\r\n");

      NetworkBitStatus.NumberOfRetries++;
      NetworkBitStatus.NumberOfTimesSent = 0;
      NetworkBitStatus.MessageExecuteStep = WIRELESS_USER_ACTION_RESPONSE;

      NetworkDelayedStartCommandOperationTask(WIRELESS_INTERVAL_OF_QUERY_EXECUTE_STATUS);
    }
    else
    {
      PRINT("[network]: command execution failed.\r\n");

      NetworkBitStatus.MessageExecuteStep = WIRELESS_MESSAGE_RESPONSE_EXCEPTION;
      NetworkStartCommandOperationTaskNoWait();
    }
  }
  break;
  }

  return ResponseResult;
}

static void NetworkReportingCommandExecutionResults(NetworkCommandTable_t Command, bool Result)
{
  switch (Command)
  {
  case NETWORK_SELF_TEST:
  {
    NetworkNotificationSelfTestResult(Result);
  }
  break;

  case NETWORK_INITIATE_NET_ATTACHMENT:
  {
    if (Result == true)
    {
      NetworkNotificationNetworkAttachmentResult(NETWORK_NET_ACCESS_SUCCESS);
    }
    else
    {
      NetworkNotificationNetworkAttachmentResult(NETWORK_NET_ACCESS_ERROR);
    }
  }
  break;

  case NETWORK_RESET_SYSTEM_STATUS:
  {
    NetworkNotificationResetResults(Result);
  }
  break;

  default:
    break;
  }
}

// tag: 串口接收
static void NetworkDataReceivedCallback(void)
{
  // PRINT("[network]: rx length: %d, data: %s.\r\n", NetworkDataPacket.DataSize, NetworkDataPacket.DataBuff);
#ifdef UART_RECEIVE_PRINT
  PRINT("[network] : uart rx length: %d, data: ", NetworkDataPacket.DataSize);
  for (uint16_t i = 0; i < NetworkDataPacket.DataSize; i++)
  {
    PRINT("%02X", NetworkDataPacket.DataBuff[i]);
  }
  PRINT("\r\n");
#endif

  if (NetworkBitStatus.TransmitIdent == true)
  {
    NetworkBitStatus.MessageExecuteStep = WIRELESS_USER_ACTION_RESPONSE;
    NetworkCommandOperationCallback();
  }

  NetworkDataPacket.DataSize = 0;
}

uint8_t GetCurrentSendBoardNumber(unsigned char MacAddress)
{
  // 遍历每一位，查找被设置为1的位
  for (uint8_t i = 0; i < 8; i++)
  { // 假设MacAddress是8位的unsigned char
    if (MacAddress & (1 << i))
    {
      return i + 1; // 恢复原始的CurrentSendBoardNumber
    }
  }
  // 如果没有位被设置，返回0或根据实际情况返回错误值
  return 0; // 或者返回一个表示无效状态的值
}

extern MutiEleBoardComuStatusMechine_t MutiEleBoardComuStatusMechine;
static void NetworkCommandOperationCallback(void)
{
  PRINT("[network]: command operation callback. NetworkBitStatus.MessageExecuteStep = %d\r\n", NetworkBitStatus.MessageExecuteStep);
  PRINT("[network]: NetworkBitStatus.CurrentCommand = %d\r\n", NetworkBitStatus.CurrentCommand);
  switch (NetworkBitStatus.MessageExecuteStep)
  {
  case WIRELESS_PREPARATION_FOR_SENDING:
  {
#if _NETWOK_MODLE_TYPE_ == _RS485_MODULE_
    NetworkBitStatus.CommandExecuteResult = true;
    NetworkBitStatus.MessageExecuteStep = WIRELESS_USER_ACTION_RESPONSE;
#if 0
  uint8_t Data[5] = {0x00, 0x01, 0x02, 0x03, 0x04};
  NetworkPushMessageToHost(Data, 5);
#endif

#else
    NetworkBitStatus.MessageExecuteStep = WIRELESS_USER_ACTION_RESPONSE;
#endif

    NetworkHardwareReset();
    NetworkInitiateDataTransfer();
    NetworkConfigurationNormalMode();
    NetworkDelayedStartCommandOperationTask(WIRELESS_WAIT_VOLTAGE_STABILIZATION_TIME);
  }
  break;

  case WIRELESS_USER_ACTION_RESPONSE:
  {
    if (NetworkBitStatus.TransmitIdent != true)
    {
      uint16_t MaxSendTimes = 0;
      // 可配置发送次数
      if (NetworkBitStatus.SettingNumberOfRetries > 0)
      {
        MaxSendTimes = NetworkBitStatus.SettingNumberOfRetries;
      }
      else
      {
        MaxSendTimes = WIRELESS_MAX_NUMBER_OF_SEND;
      }

      if (NetworkBitStatus.NumberOfTimesSent < MaxSendTimes)
      {
        uint32_t ResponseTime = 0;
        memset(&NetworkDataPacket, 0, sizeof(NetworkDataPacket_t));

        bool Ret = NetworkConstructMessageCorrespondingCommand(NetworkBitStatus.CurrentCommand, NetworkBitStatus.Parmameter, NetworkDataPacket.DataBuff, &NetworkDataPacket.DataSize, &ResponseTime);
        PRINT("[network] : ret  = %d\r\n", Ret);
        if ((NetworkDataPacket.DataSize > 0) && (NetworkDataPacket.DataSize <= NETWORK_MESSAGE_PACKET_LENGTH))
        {
          PRINT("[network]: build message success, size: %d, data: .\r\n", NetworkDataPacket.DataSize);

          {
            NetworkBitStatus.NumberOfTimesSent++;
            NetworkBitStatus.TransmitIdent = true;
            NetworkBitStatus.MessageExecuteStep = WIRELESS_MESSAGE_DELIVERY_TIMEOUT;

            if (NetworkBitStatus.SendTimeoutInterval > 0)
            {
              ResponseTime = NetworkBitStatus.SendTimeoutInterval;
            }
            else
            {
              if (ResponseTime < WIRELESS_MESSAGE_SENGING_RATED_TIME)
              {
                ResponseTime = WIRELESS_MESSAGE_SENGING_RATED_TIME;
              }
            }
          }

          {
            NetworkPushMessageToHost(NetworkDataPacket.DataBuff, NetworkDataPacket.DataSize);
            NetworkDelayedStartCommandOperationTask(ResponseTime);

            memset(&NetworkDataPacket, 0, sizeof(NetworkDataPacket_t));
          }
        }
        else
        {
          PRINT("[network]: build message error.\r\n");

          NetworkBitStatus.MessageExecuteStep = WIRELESS_COMMUNICATIONS_ANOMALY;
          NetworkStartCommandOperationTaskNoWait();
        }
      }
      else
      {
        PRINT("[network]: maximum number of transmissions exceeded.\r\n");

        NetworkBitStatus.MessageExecuteStep = WIRELESS_COMMUNICATIONS_ANOMALY;
        NetworkStartCommandOperationTaskNoWait();
      }
    }
    else // 解析
    {
      bool IsResponse = false;

      uint16_t AttachedDataSize = 0;
      ParsingResult_t ParsingResult = 0;
      uint8_t AttachedData[MESSAGE_DATA_PACKET_LENGTH] = {0};
      bool Ret = VerifyMessageValidity(NetworkDataPacket.DataBuff, AttachedData, &AttachedDataSize, &ParsingResult, &HostBitStatus.CurrentCommand);
      NetworkExecuteResult_t MessageParsingResults = NETWORK_MESSAGE_EXECUTE_ERROR;
      PRINT("[network]: VerifyMessageValidity ret = %d, AttachedDataSize = %d, AttachedData = ", Ret, AttachedDataSize);
      for (uint16_t i = 0; i < AttachedDataSize; i++)
      {
        PRINT("%02X ", AttachedData[i]);
      }
      PRINT("\r\n");

      if (Ret)
      {
        MessageParsingResults = NetworkParsingMessagesBasedOnCommands(NetworkBitStatus.CurrentCommand, AttachedData, AttachedDataSize); //
        MutiEleBoardComuStatusMechine.MutiEleBoardComuStatus = MUTI_ELE_BOARD_COMU_STATUS_SUCCESS;
        if (GetEleControlBoardNumber() > 0)
        {
          NetworkDelayedStartMutiEleBoardComuCallbackTask(0);
        }
      }
      else
      {
        PRINT("[network]: VerifyMessageValidity false\r\n");//校验失败的
        MessageParsingResults = NETWORK_MESSAGE_EXECUTE_OVER;
      }
      PRINT("[network]: MessageParsingResults = %d\r\n", MessageParsingResults);
      NetworkBitStatus.TransmitIdent = (NetworkResponseMessageParsingResult(MessageParsingResults) == true) ? false : true; // NETWORK_MESSAGE_EXECUTE_SUCCESS
      memset(&NetworkDataPacket, 0, sizeof(NetworkDataPacket_t));
    }
  }
  break;

  case WIRELESS_MESSAGE_DELIVERY_TIMEOUT:
  {
    PRINT("[network]: message delivery timeout.\r\n");

    NetworkBitStatus.TransmitIdent = false;
    NetworkBitStatus.MessageExecuteStep = WIRELESS_USER_ACTION_RESPONSE;
    uint8_t MacAddr[MAC_ADDR_CODING_LENGTH] = {0};
    GetDestinMacAddress(MacAddr);

    // uint8_t AddBit = MacAddr[5] & 0xFF;//第五个字段代表
    // PRINT("[network]: AddBit = %d\r\n", AddBit);
    uint8_t BoardNumber = GetCurrentSendBoardNumber(MacAddr[5]);
    PRINT("[network]: BoardNumber = %d\r\n", BoardNumber);


    if (EleControlBoardRetryComuniTimesArray[BoardNumber - 1] > NETWORK_RETRY_COMMUNICATION_TIMES)
    {
      MutiEleBoardComuStatusMechine.MutiEleBoardComuStatus = MUTI_ELE_BOARD_COMU_STATUS_ERROR;
    }else{
      EleControlBoardRetryComuniTimesArray[BoardNumber - 1]++;
    }

    NetworkStartCommandOperationTaskNoWait();
  }
  break;

  case WIRELESS_COMMUNICATIONS_ANOMALY:
  case WIRELESS_COMMAND_EXECUTE_FAILURE:
  case WIRELESS_MESSAGE_RESPONSE_COMPLETE:
  case WIRELESS_MESSAGE_RESPONSE_EXCEPTION:
  {
    NetworkReportingCommandExecutionResults(NetworkBitStatus.CurrentCommand, NetworkBitStatus.CommandExecuteResult);
    memset(&NetworkBitStatus, 0, sizeof(NetworkBitStatus_t));
    //Davy
    // MutiEleBoardComuStatusMechine.MutiEleBoardComuStatus = MUTI_ELE_BOARD_COMU_STATUS_IDLE;

  }
  break;

  default:
    break;
  }
}

static void NetworkAirborneAwakeningCallback(void)
{
  PRINT("[network]: radio carrier wake-up call.\r\n");

  NetworkStartKeepAlive();
  NetworkSetWakeupPinLevel(true);
}
#endif

bool NetworkGetBusyEn(void)
{
#if _NETWOK_FUNCTION_ENABLE_
  if (NetworkBitStatus.MessageBusyIdent == true)
    return true;
#endif

  return false;
}

bool NetworkInitiateSelfTestTask(void)
{
  // #if _NETWOK_FUNCTION_ENABLE_
  //   if (NetworkBitStatus.MessageBusyIdent != true)
  //   {
  //     memset(&NetworkBitStatus, 0, sizeof(NetworkBitStatus_t));

  //     NetworkBitStatus.MessageBusyIdent = true;
  //     NetworkBitStatus.CurrentCommand = NETWORK_SELF_TEST;
  //     NetworkBitStatus.MessageExecuteStep = WIRELESS_PREPARATION_FOR_SENDING;
  //     NetworkStartCommandOperationTaskNoWait();

  //     return true;
  //   }
  // #endif

  return false;
}

bool NetworkInitiateOpenSpecificFloorTask(void *Parm)
{
  PRINT("[network]: NetworkInitiateOpenSpecificFloorTask.\r\n");
  if (NetworkBitStatus.MessageBusyIdent != true)
  {
    memset(&NetworkBitStatus, 0, sizeof(NetworkBitStatus_t));

    NetworkBitStatus.MessageBusyIdent = true;
    NetworkBitStatus.CurrentCommand = NETWORK_OPEN_SPECIFIC_FLOOR;
    NetworkBitStatus.MessageExecuteStep = WIRELESS_PREPARATION_FOR_SENDING;
    NetworkBitStatus.Parmameter = (void *)Parm;
    ClearRs485BitStatus();
    NetworkStartCommandOperationTaskNoWait();
    return true;
  }
  return false;
}

bool NetworkIoBoardGetVersionTask(void *Parm)
{
  PRINT("[network]: NetworkIoBoardGetVersionTask.\r\n");
  if (NetworkBitStatus.MessageBusyIdent != true)
  {
    memset(&NetworkBitStatus, 0, sizeof(NetworkBitStatus_t));

    NetworkBitStatus.MessageBusyIdent = true;
    NetworkBitStatus.CurrentCommand = NETWORK_GET_IO_BOARD_VERSION;
    NetworkBitStatus.MessageExecuteStep = WIRELESS_PREPARATION_FOR_SENDING;
    NetworkBitStatus.Parmameter = (void *)Parm;
    NetworkStartCommandOperationTaskNoWait();
    return true;
  }
  return false;
}

bool NetworkIoBoardOpenEmergencyModeTask(void *Parm)
{
  PRINT("[network]: NetworkIoBoardOpenEmergencyModeTask.\r\n");
  if (NetworkBitStatus.MessageBusyIdent != true)
  {
    PRINT("[NetworkIoBoardOpenEmergencyModeTask]\r\n");
    memset(&NetworkBitStatus, 0, sizeof(NetworkBitStatus_t));

    NetworkBitStatus.MessageBusyIdent = true;
    NetworkBitStatus.CurrentCommand = NETWORK_OPEN_EMERGENCY_MODE;
    NetworkBitStatus.MessageExecuteStep = WIRELESS_PREPARATION_FOR_SENDING;
    NetworkBitStatus.Parmameter = (void *)Parm;
    NetworkStartCommandOperationTaskNoWait();
    return true;
  }
  PRINT("[network]: busy\r\n");
  return false;
}

// todo: 电梯io板固件传输
bool ElevatorIoBoradFirmwareTransferTask(void *Parm)
{
  PRINT("[network]: ElevatorIoBoradFirmwareTransferTask.\r\n");
  if (NetworkBitStatus.MessageBusyIdent != true)
  {
    memset(&NetworkBitStatus, 0, sizeof(NetworkBitStatus_t));

    NetworkBitStatus.MessageBusyIdent = true;
    NetworkBitStatus.CurrentCommand = NETWORK_ELEVATOR_IO_BOARD_FIRMWARE_TRANS;
    NetworkBitStatus.MessageExecuteStep = WIRELESS_PREPARATION_FOR_SENDING;
    NetworkBitStatus.Parmameter = (void *)Parm;
    NetworkDelayedStartCommandOperationTask(0);
    return true;
  }
  return false;
}

// tag: 查询io板更新状态，3s发送一次查询，最大发送20次
bool ElevatorIoBoradGetOtaStatusTask(void *Parm)
{
  PRINT("[network]: ElevatorIoBoradGetOtaStatusTask.\r\n");
  if (NetworkBitStatus.MessageBusyIdent != true)
  {
    memset(&NetworkBitStatus, 0, sizeof(NetworkBitStatus_t));
    NetworkBitStatus.MessageBusyIdent = true;
    NetworkBitStatus.CurrentCommand = NETWORK_QUERY_OTA_STATUS;
    NetworkBitStatus.MessageExecuteStep = WIRELESS_PREPARATION_FOR_SENDING;
    NetworkBitStatus.Parmameter = (void *)Parm;
    // 配置重发次数
    NetworkBitStatus.SettingNumberOfRetries = 20; // 最大发送20次
    // 配置重发间隔
    NetworkBitStatus.SendTimeoutInterval = 3000; // 3s发送一次查询
    NetworkDelayedStartCommandOperationTask(0);
    return true;
  }
  return false;
}

void SetIoBoarGetOtaStatusNumberOfRetriesAndIngerval(void)
{
  PRINT("[network_app] : SetIoBoarGetOtaStatusNumberOfRetriesAndIngerval\r\n");
  // 配置重发次数
  NetworkBitStatus.SettingNumberOfRetries = 20; // 最大发送20次
  // 配置重发间隔
  NetworkBitStatus.SendTimeoutInterval = 3000; // 3s发送一次查询
}

bool ElevatorQueryIoBoardsIsExistTask(void *Parm)
{
  PRINT("[network]: ElevatorQueryIoBoardsIsExistTask.\r\n");
  if (NetworkBitStatus.MessageBusyIdent != true)
  {
    memset(&NetworkBitStatus, 0, sizeof(NetworkBitStatus_t));
    NetworkBitStatus.MessageBusyIdent = true;
    NetworkBitStatus.CurrentCommand = NETWORK_QUERY_IO_BOARD_MAC_ADDRESS;
    NetworkBitStatus.MessageExecuteStep = WIRELESS_PREPARATION_FOR_SENDING;
    NetworkBitStatus.Parmameter = (void *)Parm;
    // 配置重发次数
    NetworkBitStatus.SettingNumberOfRetries = 3;
    // 配置重发间隔
    NetworkBitStatus.SendTimeoutInterval = 300; // 300ms
    NetworkDelayedStartCommandOperationTask(0); // 立刻启动
    return true;
  }
  return false;
}

bool NetworkSetBoardSelfTestModeTask(void *Parm)
{
  PRINT("[network]: NetworkSetBoardSelfTestModeTask.\r\n");
  if (NetworkBitStatus.MessageBusyIdent != true)
  {
    memset(&NetworkBitStatus, 0, sizeof(NetworkBitStatus_t));

    NetworkBitStatus.MessageBusyIdent = true;
    NetworkBitStatus.CurrentCommand = NETWORK_SET_BOARD_SELF_TEST_MODE;
    NetworkBitStatus.MessageExecuteStep = WIRELESS_PREPARATION_FOR_SENDING;
    NetworkBitStatus.Parmameter = (void *)Parm;
    NetworkStartCommandOperationTaskNoWait();
    return true;
  }
  return false;
}

bool NetworkSetBoardFireAlarmWorkModeTask(void *Parm)
{
  PRINT("[network]: NetworkSetBoardFireAlarmWorkModeTask.\r\n");
  if (NetworkBitStatus.MessageBusyIdent != true)
  {
    memset(&NetworkBitStatus, 0, sizeof(NetworkBitStatus_t));
    
    PRINT("[network]: pFireAlarmMode\r\n");

    NetworkBitStatus.MessageBusyIdent = true;
    NetworkBitStatus.CurrentCommand = NETWORK_SET_BOARD_FIRE_ALARM_WORK_MODE;
    NetworkBitStatus.MessageExecuteStep = WIRELESS_PREPARATION_FOR_SENDING;
    NetworkBitStatus.Parmameter = (void *)Parm;
    NetworkStartCommandOperationTaskNoWait();
    return true;
  }
  return false;
}

bool NetworkQueryBoardFireAlarmStatusTask(void *Parm)
{
  if (NetworkBitStatus.MessageBusyIdent != true)
  {
    memset(&NetworkBitStatus, 0, sizeof(NetworkBitStatus_t));

    NetworkBitStatus.MessageBusyIdent = true;
    NetworkBitStatus.CurrentCommand = NETWORK_QUERY_BOARD_FIRE_ALARM_STATUS;
    NetworkBitStatus.MessageExecuteStep = WIRELESS_PREPARATION_FOR_SENDING;
    NetworkBitStatus.Parmameter = (void *)Parm;
    NetworkStartCommandOperationTaskNoWait();
    return true;
  }
  return false;
}

bool NetworkInitiateNetworkAttachmentTask(void)
{
#if _NETWOK_FUNCTION_ENABLE_
  NetworkNotificationNetworkAttachmentResult(NETWORK_NET_ACCESSING);

  memset(&NetworkBitStatus, 0, sizeof(NetworkBitStatus_t));
  NetworkBitStatus.MessageBusyIdent = true;
  NetworkBitStatus.CurrentCommand = NETWORK_INITIATE_NET_ATTACHMENT;
  NetworkBitStatus.MessageExecuteStep = WIRELESS_PREPARATION_FOR_SENDING;
  NetworkStartCommandOperationTaskNoWait();

#else
  return true;
  return false;
#endif
}

bool NetworkInitiateDeviceResetTask(void)
{
#if _NETWOK_FUNCTION_ENABLE_
  memset(&NetworkBitStatus, 0, sizeof(NetworkBitStatus_t));

  NetworkBitStatus.MessageBusyIdent = true;
  NetworkBitStatus.CurrentCommand = NETWORK_RESET_SYSTEM_STATUS;
  NetworkBitStatus.MessageExecuteStep = WIRELESS_PREPARATION_FOR_SENDING;
  NetworkStartCommandOperationTaskNoWait();

  return true;
#else
  return false;
#endif
}

bool NetworkStartExitCommandModeTask(void)
{
#if _NETWOK_FUNCTION_ENABLE_
  memset(&NetworkBitStatus, 0, sizeof(NetworkBitStatus_t));

  NetworkBitStatus.MessageBusyIdent = true;
  NetworkBitStatus.CurrentCommand = NETWORK_FORCE_EXIT_COMMAND_MODE;
  NetworkBitStatus.MessageExecuteStep = WIRELESS_PREPARATION_FOR_SENDING;
  NetworkStartCommandOperationTaskNoWait();

  return true;
#else
  return false;
#endif
}

bool NetworkPushMessageToHost(const uint8_t *pMessageIn, uint16_t SizeOfMessage)
{
#if _NETWOK_FUNCTION_ENABLE_
  NetworkSetSendEnablePinLevel(true);
  NetWorkSendDataToHost(pMessageIn, SizeOfMessage);
  // NetworkDelayMs(10);
  NetworkSetSendEnablePinLevel(false);
  return true;
#else
  return false;
#endif
}

void NetworkResetWorkingStatus(void)
{
#if _NETWOK_FUNCTION_ENABLE_
  NetworkStopCommandOperationTask();

  memset(&NetworkBitStatus, 0, sizeof(NetworkBitStatus_t));
  memset(&NetworkDataPacket, 0, sizeof(NetworkDataPacket_t));
#endif
}

void NetworkIntoPowerDown(void)
{
#if _NETWOK_FUNCTION_ENABLE_
  NetworkConfigurationLowPower();
#endif
}

// static MutiEleBoardComuStatusMechineEnum_t MutiEleBoardComuStatusMechine = MUTI_ELE_BOARD_COMU_STATUS_IDLE;
MutiEleBoardComuStatusMechine_t MutiEleBoardComuStatusMechine = {0};

/**
 * @brief 多电梯板通信回调函数
 *
 * @param Handler 处理函数指针 是NetworkSetBoardSelfTestModeTask类似的参数
 * @param Parm 处理参数
 */
void NetworkMutiEleBoardCommuni(MutiEleBoardComuHandler_t Handler, void *Parm)
{
  WwdgFeedWatchdog();
  PRINT("[network]: NetworkMutiEleBoardCommuni. MutiEleBoardComuStatusMechine.MutiEleBoardComuStatus = %d\r\n", MutiEleBoardComuStatusMechine.MutiEleBoardComuStatus);
  if (MutiEleBoardComuStatusMechine.MutiEleBoardComuStatus == MUTI_ELE_BOARD_COMU_STATUS_IDLE)
  {
    MutiEleBoardComuStatusMechine.MutiEleBoardComuStatus = MUTI_ELE_BOARD_COMU_STATUS_READY;
    MutiEleBoardComuStatusMechine.SumSendBoardNumber = GetEleControlBoardNumber();
    PRINT("[network]: NetworkMutiEleBoardCommuni. MutiEleBoardComuStatusMechine.SumSendBoardNumber = %d\r\n", MutiEleBoardComuStatusMechine.SumSendBoardNumber);
    MutiEleBoardComuStatusMechine.CurrentSendBoardNumber = 1; // 从第一个开始
    NetworkStartMutiEleBoardComuCallbackTaskNoWait();         // 第一次启动状态机
    MutiEleBoardComuStatusMechine.Handler = Handler;
    MutiEleBoardComuStatusMechine.Parm = Parm;
    return;
  }

  if (Handler != NULL)
  {
    PRINT("[network]: NetworkMutiEleBoardCommuni Handler \r\n");
    // 执行开始
    Handler(Parm);
  }
  else
  {
    PRINT("[network]: NetworkMutiEleBoardCommuni Handler or Parm is NULL.\r\n");
    return;
  }

}

#define NETWORK_MUTI_ELE_BOARD_COMU_DELAY_TIME_MS 500 // 0.5s调用一次
extern void RfidExitCardDetectionMode(void);
// 事件状态机Davy
static void NetworkMutiEleBoardComuCallback(void)
{
  PRINT("[network]: NetworkMutiEleBoardComuCallback.\r\n");
  uint8_t MacAddress[MAC_ADDR_CODING_LENGTH] = {0};
  // 状态机
  PRINT("[network]: NetworkMutiEleBoardComuCallback. MutiEleBoardComuStatusMechine.MutiEleBoardComuStatus = %d.\r\n", MutiEleBoardComuStatusMechine.MutiEleBoardComuStatus);
  switch (MutiEleBoardComuStatusMechine.MutiEleBoardComuStatus)
  {
  case MUTI_ELE_BOARD_COMU_STATUS_READY:

    MacAddress[5] = (1 << (MutiEleBoardComuStatusMechine.CurrentSendBoardNumber - 1));
    SetDestinMacAddress(MacAddress);
    
    NetworkMutiEleBoardCommuni(MutiEleBoardComuStatusMechine.Handler, MutiEleBoardComuStatusMechine.Parm);
    MutiEleBoardComuStatusMechine.MutiEleBoardComuStatus = MUTI_ELE_BOARD_COMU_STATUS_IS_RUNNING;
    NetworkDelayedStartMutiEleBoardComuCallbackTask(NETWORK_MUTI_ELE_BOARD_COMU_DELAY_TIME_MS);

    break;
  case MUTI_ELE_BOARD_COMU_STATUS_IS_RUNNING: // 持续查状态
    // MutiEleBoardComuStatusMechine.MutiEleBoardComuStatus = MUTI_ELE_BOARD_COMU_STATUS_SUCCESS;
    NetworkDelayedStartMutiEleBoardComuCallbackTask(NETWORK_MUTI_ELE_BOARD_COMU_DELAY_TIME_MS);
    break;
  case MUTI_ELE_BOARD_COMU_STATUS_SUCCESS:

    if (MutiEleBoardComuStatusMechine.CurrentSendBoardNumber < MutiEleBoardComuStatusMechine.SumSendBoardNumber)
    {
      MutiEleBoardComuStatusMechine.CurrentSendBoardNumber++;
      MutiEleBoardComuStatusMechine.MutiEleBoardComuStatus = MUTI_ELE_BOARD_COMU_STATUS_READY;
      PRINT("MutiEleBoardComuStatusMechine.CurrentSendBoardNumber = %d, MutiEleBoardComuStatusMechine.SumSendBoardNumber = %d.\r\n", MutiEleBoardComuStatusMechine.CurrentSendBoardNumber, MutiEleBoardComuStatusMechine.SumSendBoardNumber);
    }
    else
    {
      MutiEleBoardComuStatusMechine.MutiEleBoardComuStatus = MUTI_ELE_BOARD_COMU_STATUS_OVER;
    }
    if (MutiEleBoardComuStatusMechine.MutiEleBoardComuStatus != MUTI_ELE_BOARD_COMU_STATUS_IDLE)
    {
      NetworkDelayedStartMutiEleBoardComuCallbackTask(0);
    }
    break;
  case MUTI_ELE_BOARD_COMU_STATUS_OVER:
    // 清空状态机以及所有数据
    PRINT("[network_app] : MUTI_ELE_BOARD_COMU_STATUS_OVER.\r\n");
    memset(&MutiEleBoardComuStatusMechine, 0, sizeof(MutiEleBoardComuStatusMechine));
    MutiEleBoardComuStatusMechine.MutiEleBoardComuStatus = MUTI_ELE_BOARD_COMU_STATUS_IDLE;
    break;
  case MUTI_ELE_BOARD_COMU_STATUS_ERROR:
    // 停止状态机
    PRINT("[network_app] : MUTI_ELE_BOARD_COMU_STATUS_ERROR.\r\n");
    // 亮红灯，同时关闭读卡功能
    AlarmLedNormalTurnOn();
    RfidExitCardDetectionMode();
    memset(&MutiEleBoardComuStatusMechine, 0, sizeof(MutiEleBoardComuStatusMechine));
    MutiEleBoardComuStatusMechine.MutiEleBoardComuStatus = MUTI_ELE_BOARD_COMU_STATUS_IDLE;
    break;
  default:
    PRINT("[network_app] : default.\r\n");
    break;
  }
}

#define _OPEN_TEST_NUM_ 6 // test: Davy

#if (_OPEN_TEST_NUM_ == 1)
ElectorData_t ElectorData = {0};
#elif (_OPEN_TEST_NUM_ == 2)
IoBoardFirmwareInfo_t IoBoardFirmwareInfo = {0};
#elif (_OPEN_TEST_NUM_ == 3)
uint8_t Data[1] = {0x01};
#elif (_OPEN_TEST_NUM_ == 4)
uint8_t Data[1] = {0x01};
#elif (_OPEN_TEST_NUM_ == 5)
uint8_t Data[1] = {0x01};
#else
// uint8_t Data[1] = {0x01};
#endif

void NetworkConfiguration(void)
{
#if _NETWOK_FUNCTION_ENABLE_
  memset(&NetworkBitStatus, 0, sizeof(NetworkBitStatus_t));

  NetworkExternFunctionTable_t ExternFunction = {0};
  ExternFunction.UartRxDoneCallBack = NetworkDataReceivedCallback;
  ExternFunction.CommandOperationCallback = NetworkCommandOperationCallback;
  ExternFunction.AirborneAwakeningCallback = NetworkAirborneAwakeningCallback;
  ExternFunction.MutiEleBoardComuCallback = NetworkMutiEleBoardComuCallback;
  NetworkBoardBoardInitialisation(&NetworkTaskApi, &ExternFunction, &NetworkDataPacket);
#endif

#if (_OPEN_TEST_NUM_ == 1)
  ElectorData.User = 0;
  ElectorData.DirectModeFlag = 1;
  memset(&ElectorData.ElectorFloorData, 1, sizeof(ElectorData.ElectorFloorData));
  NetworkInitiateOpenSpecificFloorTask(&ElectorData);
#elif (_OPEN_TEST_NUM_ == 2)
  memset(&IoBoardFirmwareInfo.DataBuffer, 0xFF, sizeof(IoBoardFirmwareInfo.DataBuffer));
  IoBoardFirmwareInfo.DataBufferSize = 502;
  IoBoardFirmwareInfo.CurrentSendPackageSeqNumber = 0;
  IoBoardFirmwareInfo.IoBoardFirmwareSumSize = 502;
  ElevatorIoBoradFirmwareTransferTask(&IoBoardFirmwareInfo);
#elif (_OPEN_TEST_NUM_ == 3)
  uint8_t Addr[MAC_ADDR_CODING_LENGTH] = {0};
  Addr[5] = 1;
  SetDestinMacAddress(Addr);
  NetworkIoBoardGetVersionTask(&Data[0]);
#elif (_OPEN_TEST_NUM_ == 4)
  NetworkIoBoardOpenEmergencyModeTask(&Data[0]);
#elif (_OPEN_TEST_NUM_ == 5)
  ElevatorIoBoradGetOtaStatusTask(&Data[0]);
#elif (_OPEN_TEST_NUM_ == 6)
  // uint8_t Addr[MAC_ADDR_CODING_LENGTH] = {0};
  // Addr[5] = 1;
  // SetDestinMacAddress(Addr);
  // ElevatorQueryIoBoardsIsExistTask(&Data[0]);
#else

#endif
}
